home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9207.ZIP / AVKCAPT.ZIP / ACMAIN.C < prev    next >
C/C++ Source or Header  |  1992-04-01  |  21KB  |  790 lines

  1. //-------------------------------------------------------------------------
  2. //            ActionMedia II Programmer's Toolkit
  3. //            
  4. //            Windows Motion Capture Sample Program
  5. //
  6. // Application:    AvkCapt.exe
  7. // Module Name:    acmain.c
  8. //
  9. // Description:    Main module for avk motion capture program.
  10. //        Contains program entry point (WinMain), windows
  11. //        message processing functions, and dialog box procs.
  12. //
  13. // Copyright Intel Corp. 1991, 1992
  14. // All Rights Reserved.
  15. //
  16. //-------------------------------------------------------------------------
  17. //
  18. // Exported functions from this module:
  19. //
  20. //        WinMain
  21. //        MainWndProc
  22. //        AboutDlgProc
  23. //        OpenFileDlgProc
  24. //
  25. //-------------------------------------------------------------------------
  26. //
  27. // Functions local to this module:
  28. //
  29. //        InitApplication
  30. //        InitInstance
  31. //        MsgCommand
  32. //        GetFileName
  33. //
  34. //-------------------------------------------------------------------------
  35.  
  36. //-------------------------------------------------------------------------
  37. //
  38. //    NOTES ON AvkCapt
  39. //    
  40. //    AvkCapt is a simple motion capture program.  It premonitors from 
  41. //    the digitizer on CS2, the capture board.  When the user toggles
  42. //    on Capture, AvkCapt begins capturing the incoming frames and writing
  43. //    them out to a file.  
  44. //
  45. //    AvkCapt uses the AVKIO file I/O subsystem to create an AVSS file and
  46. //    to manage writing and updating the header information.  Video and
  47. //    audio frames are retrieved separately from their respective buffers.
  48. //    The AVKIO function AvioFileFrmWrite() is used to write interleaved
  49. //    video and audio frames to the AVSS file.
  50. //    
  51. //    AvkCapt will capture either NTSC 30-fps or PAL 25-fps files using the
  52. //    RTV 2.0 compression algorithm for video and the ADPCM4 algorithm for 
  53. //    audio. It calls AvkDeviceVideoIn to determine the capture source sync.
  54. //    It formats a video stream to 128x240 (NTSC) or 128x244 (PAL) for 
  55. //    capture.  Since RTV 2.0 will double the horizontal pixels, the 
  56. //    end result is a 256x240 (NTSC) or 256x288 (PAL) file for later
  57. //    playback.  Since the horizontal resolution of the playback stream 
  58. //    is only 128, though, we can't show the premonitored video at
  59. //    full-screen size on our 256x240 VGA view.  This is because we can't
  60. //    scale up using a connector.  In AVK, if the destination is larger than
  61. //    the source, the image will be displayed in the upper left hand corner 
  62. //    of the destination box.  Therefore, AvkCapt uses a fixed window of 
  63. //    128x120 pixels to display the premonitored video.
  64. //                                   
  65. //    The most difficult element of capturing incoming digitized data is
  66. //    keeping up with it.  If an AVK program does not read the frames
  67. //    from the VRAM buffers fast enough with calls to AvkGrpBufRead(), then
  68. //    frames will be lost and a series of blank frames will be inserted to
  69. //    take their place causing skipping effects on playback.  On the other
  70. //    hand, if the program spends too much time retrieving data, it may be
  71. //    neglecting to process the message loop promptly and mouse action may
  72. //    degrade.
  73. //    
  74. //    There are basically two different approaches to retrieving data in a
  75. //    timely manner.  AvkCapt gives simple examples of both.  The first
  76. //    technique involves calling our read routine each time AvkCapt receives
  77. //    a message from AVK informing it that a designated amount of data has
  78. //    been captured into a VRAM Group Buffer.  AVK sends the
  79. //    AVK_CAPTURE_DATA_AVAILABLE message whenever the data in a VRAM buffer
  80. //    exceeds the hunger granularity level the application has set when
  81. //    creating the Group Buffer.  The read routine then retrieves as much
  82. //    data from the VRAM buffer as it can handle, parses it into frames and
  83. //    writes out as many frames as it can to the AVSS file before exiting.
  84. //    The application returns to processing the message loop and awaits the
  85. //    next AVK_CAPTURE_DATA_AVAILABLE message.
  86. //    
  87. //    The second method (enabled by selecting the 'Timer' option from the 
  88. //    'File' popup menu) involves setting up a Windows timer and calling 
  89. //    the same read routine on each timer tick.  Note that we are using a 
  90. //    timer tick of 200 milliseconds to call CaptureAvioData(). This will 
  91. //    result in a maximum of approximately 5 calls per second.  The capture
  92. //    function has to write about 6 frames a call to keep up.  Since 
  93. //    CaptureAvioData() is likely to write out more than that if more data
  94. //    is present, timer messages may back up.  Windows will discard backed
  95. //    up timer ticks if one is already waiting in the queue, so this is
  96. //    no problem.  The TIMER_INTERVAL #define in AvkCapt.h can be altered
  97. //    to change this interval.  
  98. //
  99. //    AvkCapt's performance in capturing can be tuned by varying the above-
  100. //    mentioned TIMER_INTERVAL, the #defined value for CAPTURE_LOOPS (which
  101. //    dictates how many iterations of the read/write loop will be executed
  102. //    in CaptureAvioData() before it is forced back to the main message 
  103. //    loop) and the #defined size of the host buffers, HOST_BUF_SIZE. 
  104. //    
  105. //    An additional improvement may be obtained by changing the timer
  106. //    tick logic to have the timer call CaptureAvioData() directly (don't
  107. //    forget to use a Proc Instance for this).
  108. //
  109. //-------------------------------------------------------------------------
  110.  
  111. #include <windows.h>
  112. #include <stdio.h>
  113. #include <string.h>
  114. #include "avkapi.h"
  115. #include "avkcapt.h"
  116. #include "disperr.h"
  117. #include "avkio.h"
  118. #include "log.h"
  119.  
  120. //-------------------------------------------------------------------------
  121. //    Local variables
  122. //-------------------------------------------------------------------------
  123.  
  124. HWND    hwndMain;
  125. HANDLE    hInst;
  126.  
  127. char    szMainMenu[] = "MainMenu";       // main menu name
  128. char    szWndClass[] = "AvkCaptClass";    // main window class
  129. char    AvssFileName[128] = {'\0'};    // we build the AVSS file name here
  130. BOOL    bDstBoxInitialized = FALSE;    // TRUE after View.DstBox is first set
  131. BOOL    bTimedCapture = FALSE;        // TRUE if timed capturing selected
  132.  
  133. char    *pStateName[] =
  134. {
  135.     "UNINITIALIZED",
  136.     "INITIALIZED",
  137.     "MONITORING",
  138.     "CAPTURING"
  139. };
  140.  
  141. //-------------------------------------------------------------------------
  142. //    External functions.
  143. //-------------------------------------------------------------------------
  144.  
  145. extern BOOL        InitAvk(void);
  146. extern BOOL        CreateAvkResources(WORD);
  147. extern BOOL        EndAvk(void);
  148. extern BOOL        MonitorOn(void);
  149. extern BOOL        MonitorOff(void);
  150.  
  151. //-------------------------------------------------------------------------
  152. //    Local functions.
  153. //-------------------------------------------------------------------------
  154.  
  155. LONG FAR PASCAL        MainWndProc(HWND, WORD, WORD, LONG);
  156. BOOL FAR PASCAL        AboutDlgProc(HWND, WORD, WORD, LONG);
  157. BOOL FAR PASCAL        OpenDlgProc(HWND, WORD, WORD, LONG);
  158. BOOL            InitApplication(HANDLE);
  159. BOOL            InitInstance(HANDLE, int);
  160. BOOL            MsgCommand(HWND, WORD, WORD, LONG);
  161. BOOL            GetFileName(HWND);
  162.  
  163. //--------------------------------------------------------------------------
  164. //FUNCTION:                        
  165. //    
  166. //    int WinMain(hInst, hPrevInst, lpszCmdLine, nCmdShow)
  167. //
  168. //PARMS IN:
  169. //
  170. //    HANDLE hInst        this instance's handle
  171. //    HANDLE hPrevInst      handle to previous instance or NULL
  172. //                if no previous instance exists
  173. //    LPSTR lpszCmdLine    far pointer to the command line string
  174. //    int nCmdShow        whether to show an icon or the window
  175. //    
  176. //DESCRIPTION:
  177. //
  178. //    Windows entry point.  It initializes the application and instance
  179. //    data.  Prevents multiple instances.  It then opens the AVK session and
  180. //    enters the Windows message loop.  On exit, it closes the AVK session.
  181. //    
  182. //RETURN:
  183. //
  184. //    16-bit parameter value from WM_QUIT message.
  185. //    
  186. //-------------------------------------------------------------------------
  187.  
  188. int PASCAL
  189. WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
  190. {
  191.     MSG    Msg;
  192.     int    Ret = 0;
  193.  
  194.     // Prevent multiple instances.
  195.  
  196.     if (!hPrevInstance)
  197.     {
  198.         // Initialize window data and register the main and 
  199.         // image window classes.
  200.  
  201.         if (InitApplication(hInstance))
  202.         {
  203.             // Create main window and the image display window.
  204.  
  205.             if (InitInstance(hInstance, nCmdShow))
  206.             {
  207.  
  208.                 MessageBox(GetFocus(),
  209.                   "Do not switch to a full-screen DOS "
  210.                   "session while Monitoring is On.",
  211.                   "AvkCapt", MB_ICONASTERISK | MB_OK);
  212.  
  213.                 // Open an AVK session.
  214.  
  215.                 if (InitAvk())
  216.                 {
  217.  
  218.                     // Operate the message loop
  219.                     // until a WM_QUIT is received.
  220.  
  221.                     while (GetMessage(&Msg, NULL, NULL, NULL))
  222.                     {
  223.                         TranslateMessage(&Msg);
  224.                         DispatchMessage(&Msg);
  225.                     }
  226.                 }
  227.  
  228.                 // Close AVK and return the PostQuit message's
  229.                 // wParam value.
  230.  
  231.                 EndAvk();
  232.                 Ret = Msg.wParam;
  233.             }
  234.         }
  235.     }
  236.     else    
  237.         // Oops, another instance is running.  Display an error 
  238.         //    message and go away.
  239.  
  240.           MessageBox(GetFocus(), "Another instance is already running", 
  241.           "AvkCapt", MB_ICONASTERISK | MB_OK);
  242.  
  243.     return Ret;
  244. }
  245.  
  246. //-------------------------------------------------------------------------
  247. //FUNCTION:
  248. //
  249. //    BOOL InitApplication(hInst)
  250. //
  251. //PARMS IN:
  252. //
  253. //    HANDLE hInst        handle for current instance
  254. //
  255. //DESCRIPTION:
  256. //
  257. //    Initializes the windows data and registers the window class.
  258. //
  259. //RETURN:
  260. //
  261. //    Value returned from call to RegisterClass().
  262. //
  263. //-------------------------------------------------------------------------
  264.  
  265. BOOL
  266. InitApplication(HANDLE hInstance)
  267. {
  268.     WNDCLASS    Wc;
  269.  
  270.     Wc.style        = CS_HREDRAW | CS_VREDRAW;
  271.     Wc.lpfnWndProc        = MainWndProc;
  272.     Wc.cbClsExtra        = 0;
  273.     Wc.cbWndExtra         = 0;
  274.     Wc.hInstance        = hInstance;
  275.     Wc.hIcon        = LoadIcon(hInstance, "AvkCaptIcon");
  276.     Wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  277.     Wc.hbrBackground     = GetStockObject(BLACK_BRUSH);
  278.     Wc.lpszMenuName        = szMainMenu;
  279.     Wc.lpszClassName     = szWndClass;
  280.  
  281.     return RegisterClass(&Wc);
  282. }
  283.  
  284.  
  285. //-------------------------------------------------------------------------
  286. //FUNCTION:
  287. //
  288. //    BOOL InitInstance(HANDLE, int)
  289. //
  290. //PARMS IN:
  291. //
  292. //    HANDLE     hInstance        handle for current instance
  293. //    int    nCmdShow        show as window or icon
  294. //
  295. //DESCRIPTION:
  296. //
  297. //    Saves the instance handle to a global and creates the main window.
  298. //
  299. //RETURN:
  300. //
  301. //    TRUE    if window is created.
  302. //    FALSE    if call to CreateWindow() failed.
  303. //
  304. //-------------------------------------------------------------------------
  305.  
  306. BOOL
  307. InitInstance(HANDLE hInstance, int nCmdShow)
  308. {
  309.     WORD    cxScrn,cyScrn;
  310.     WORD    cxWindow, cyWindow;
  311.     RECT    Rect;
  312.     DWORD    Style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
  313.  
  314.     cxScrn = GetSystemMetrics(SM_CXSCREEN);
  315.     cyScrn = GetSystemMetrics(SM_CYSCREEN);
  316.  
  317.  
  318.     Rect.left = 0;
  319.     Rect.top = 0;
  320.     Rect.right = cxScrn >> 1;
  321.     Rect.bottom = cyScrn >> 1;
  322.  
  323.     AdjustWindowRect((LPRECT)&Rect, Style, TRUE);
  324.  
  325.     cxWindow = Rect.right - Rect.left;
  326.     cyWindow = Rect.bottom - Rect.top;
  327.  
  328.     hInst = hInstance;    // save the instance handle
  329.  
  330.     // Get the screen coordinates.
  331.  
  332.     hwndMain = CreateWindow(
  333.             szWndClass,
  334.             "AvkCapt - UNINITIALIZED",
  335.             Style,
  336.             (cxScrn - cxWindow) >> 1,
  337.             (cyScrn - cyWindow) >> 1,
  338.             cxWindow,
  339.             cyWindow, 
  340.             NULL,
  341.             NULL,
  342.             hInstance,
  343.             NULL);
  344.  
  345.     if (!hwndMain)
  346.         return FALSE;
  347.  
  348.     ShowWindow(hwndMain, nCmdShow);
  349.     UpdateWindow(hwndMain);
  350.  
  351.     LogOpen("DC.LOG");
  352.  
  353.     return TRUE;
  354. }
  355.  
  356. //-------------------------------------------------------------------------
  357. //FUNCTION:
  358. //
  359. //    long FAR PASCAL MainWndProc(HWND hWnd, WORD Msg, WORD wParam, LONG lParam)
  360. //    
  361. //PARMS IN:
  362. //    
  363. //    HWND    hWnd;            window handle
  364. //    WORD    Msg;            type of message
  365. //    WORD    wParam;            16-bit message parameter
  366. //    LONG    lParam;            32-bit message parameter
  367. //    
  368. //DESCRIPTION:
  369. //
  370. //    Main window proc - processes messages received by the main window.
  371. //
  372. //RETURN:
  373. //
  374. //    TRUE    if window is created.
  375. //    FALSE    if call to CreateWindow() failed.
  376. //
  377. //-------------------------------------------------------------------------
  378.  
  379. long FAR PASCAL
  380. MainWndProc(HWND hWnd, WORD Msg, WORD wParam, LONG lParam)
  381. {
  382.     switch (Msg)
  383.     {
  384.         case WM_TIMER:
  385.             if (bTimedCapture && IsState(ST_CAPTURING))
  386.             {
  387.                 if (!CaptureAvioData())
  388.                     DestroyWindow(hWnd);
  389.             }
  390.             return 0L;
  391.  
  392.         case WM_MOVE:
  393.             if (!SetDstBox(hWnd))
  394.                 DestroyWindow(hWnd);
  395.             return 0L;
  396.  
  397.         case WM_SIZE:
  398.             return 0L;
  399.  
  400.         case WM_COMMAND:
  401.             if (!MsgCommand(hWnd, Msg, wParam, lParam))
  402.                 DestroyWindow(hWnd);
  403.             return 0L;
  404.  
  405.         case AVK_CAPTURE_DATA_AVAILABLE:
  406.             // AVK has notified us that capture data is waiting
  407.             // to be written out.
  408.             if (!bTimedCapture && IsState(ST_CAPTURING))
  409.             {
  410.                 if (!CaptureAvioData())
  411.                     DestroyWindow(hWnd);
  412.             }
  413.             return 0L;
  414.  
  415.         case AVK_GROUP_PAUSED:
  416.             // Receipt of paused message indicates capture off.
  417.             ToState(ST_MONITORING);
  418.             return 0L;
  419.  
  420.         case AVK_IDENTIFY:
  421.             // We requested the digitizer source sync
  422.             // (NTSC vs PAL) during initialization.
  423.             // AVK_IDENTIFY has that sync value as the low word
  424.             // of lParam. Continue initializing
  425.             // now that we have the sync.
  426.             if (!CreateAvkResources(LOWORD(lParam)))
  427.                 DestroyWindow(hWnd);
  428.             return 0L;
  429.  
  430.         case WM_DESTROY:
  431.             // Just in case we get closed while capturing,
  432.             // close the capture file in an orderly manner.
  433.             // This causes final update information to be
  434.             // written to the file preventing a corrupted
  435.             // AVSS file.
  436.                 
  437.             CloseAvioFile();
  438.  
  439.             if (bTimedCapture)
  440.                 KillTimer(hWnd, TIMER_ID);
  441.             PostQuitMessage(0);
  442.             return 0L;
  443.     }
  444.     return DefWindowProc(hWnd, Msg, wParam, lParam);
  445. }
  446.  
  447. //-------------------------------------------------------------------------
  448. //FUNCTION:
  449. //
  450. //    LONG MsgCommand(hWnd, Msg, wParam, lParam)
  451. //
  452. //PARMS IN:
  453. //
  454. //    HWND hWnd;            // window handle
  455. //    WORD Msg;            // message
  456. //    WORD wParam;        // 16-bit message parameter
  457. //    LONG lParam;        // 32-bit message parameter
  458. //
  459. //PARMS OUT:
  460. //
  461. //    None
  462. //
  463. //DESCRIPTION:
  464. //
  465. //    Processes WM_COMMAND messages for the Main Window Proc.
  466. //
  467. //RETURN:
  468. //
  469. //    TRUE on success
  470. //    FALSE on error from AVK
  471. //
  472. //-------------------------------------------------------------------------
  473.                     
  474. BOOL
  475. MsgCommand(HWND hWnd, WORD Msg, WORD wParam, LONG lParam)
  476. {
  477.     FARPROC    lpThunk;
  478.  
  479.     switch (wParam)
  480.     {
  481.         case IDM_EXIT:
  482.             CloseAvioFile();
  483.             return FALSE;
  484.             break;
  485.  
  486.         case IDM_OPEN:
  487.             if (GetFileName(hWnd))
  488.             {
  489.                 if (!OpenAvioFile(AvssFileName))
  490.                     return FALSE;
  491.                 EnableMenuItem(GetMenu(hWnd), IDM_OPEN, MENUITEM_OFF);
  492.                 EnableMenuItem(GetMenu(hWnd), IDM_CLOSE, MENUITEM_ON);
  493.             }
  494.             break;
  495.  
  496.         case IDM_CLOSE:
  497.             if (!CloseAvioFile())
  498.                 return FALSE;
  499.             EnableMenuItem(GetMenu(hWnd), IDM_OPEN, MENUITEM_ON);
  500.             EnableMenuItem(GetMenu(hWnd), IDM_CLOSE, MENUITEM_OFF);
  501.             break;
  502.  
  503.         case IDM_ABOUT:
  504.             lpThunk = MakeProcInstance(AboutDlgProc, hInst);
  505.             DialogBox(hInst, "AboutBox", hWnd, lpThunk);
  506.             FreeProcInstance(lpThunk);
  507.             break;
  508.  
  509.         case IDM_MONITOR:
  510.             if (!ToggleMonitor())
  511.                 return FALSE;
  512.             break;
  513.  
  514.         case IDM_CAPTURE:
  515.             if (!ToggleCapture())
  516.                 return FALSE;
  517.             break; 
  518.  
  519.         case IDM_TIMER:
  520.             if (bTimedCapture = !bTimedCapture)
  521.             {
  522.                 if (!SetTimer(hWnd, TIMER_ID, TIMER_INTERVAL, NULL))
  523.                     bTimedCapture = FALSE;
  524.             }
  525.             else
  526.                 KillTimer(hWnd, TIMER_ID);
  527.  
  528.             CheckMenuItem(GetMenu(hWnd), IDM_TIMER, bTimedCapture ? 
  529.               MF_CHECKED : MF_UNCHECKED);
  530.             break;
  531.  
  532.     }
  533.     return TRUE;
  534. }
  535.  
  536.  
  537. //-------------------------------------------------------------------------
  538. //FUNCTION:
  539. //
  540. //    BOOL FAR PASCAL About(HWND hDlg, WORD Msg, WORD wParam, LONG lParam)
  541. //
  542. //PARMS IN:
  543. //
  544. //    HWND    hDlg;            window handle for the dialog box
  545. //    WORD    Msg;            type of message
  546. //    WORD    wParam;            16-bit message parameter
  547. //    LONG    lParam;            32-bit message parameter
  548. //    
  549. //PARMS OUT:
  550. //    
  551. //    None
  552. //    
  553. //DESCRIPTION:
  554. //
  555. //    About Box Dlg Proc - processes the About dialog box messages - exits
  556. //    when the OKAY button is pressed or the system menu is used to close
  557. //    the dialog box.
  558. //
  559. //RETURN:
  560. //
  561. //    TRUE if an IDOK message is received.
  562. //    FALSE if an IDCANCEL message is received
  563. //
  564. //-------------------------------------------------------------------------
  565.  
  566. BOOL FAR PASCAL
  567. AboutDlgProc(HWND hDlg, WORD Msg, WORD wParam, LONG lParam)
  568. {
  569.     switch (Msg)
  570.     {
  571.         case WM_INITDIALOG:
  572.             return TRUE;
  573.  
  574.         case WM_COMMAND:
  575.             switch (wParam)
  576.             {
  577.                 case IDCANCEL:
  578.                 case IDOK:
  579.                     EndDialog(hDlg, TRUE);
  580.                     return TRUE;
  581.             }
  582.             break;
  583.     }
  584.     return FALSE;
  585. }
  586.  
  587.  
  588. //-------------------------------------------------------------------------
  589. //FUNCTION:    
  590. //    
  591. //    BOOL GetFileName(hWnd)
  592. //
  593. //PARMS IN:
  594. //
  595. //    HWND hWnd;        main window handle
  596. //    
  597. //DESCRIPTION:
  598. //
  599. //    This function invokes the 'SaveImage' dialog box.
  600. //    
  601. //    
  602. //RETURN:
  603. //
  604. //    TRUE if a filename was entered.
  605. //    FALSE if not.
  606. //    
  607. //-------------------------------------------------------------------------
  608.  
  609. BOOL
  610. GetFileName(HWND hWnd)
  611. {
  612.     FARPROC    lpThunk;
  613.     int        Ret;
  614.  
  615.     *AvssFileName = '\0';
  616.  
  617.     // Make a proc instance of the dialog box proc and invoke it.
  618.  
  619.     lpThunk = MakeProcInstance(OpenDlgProc, hInst);
  620.     Ret = DialogBox(hInst, "OpenFile", hWnd, lpThunk);
  621.     FreeProcInstance(lpThunk);
  622.     
  623.     // Returns TRUE if a filename was selected. Check for a null length
  624.     // string.
  625.  
  626.     if (Ret == FALSE || *AvssFileName == '\0')
  627.         return FALSE;
  628.  
  629.     return TRUE;
  630. }
  631.  
  632. //-------------------------------------------------------------------------
  633. //FUNCTION:
  634. //
  635. //    long FAR PASCAL OpenDlgProc(HWND hDlg, WORD Msg, WORD wParam, 
  636. //            LONG lParam)
  637. //    
  638. //PARMS IN:
  639. //    
  640. //    HWND    hDlg;            dialog box handle
  641. //    WORD    Msg;            type of message
  642. //    WORD    wParam;            16-bit message parameter
  643. //    LONG    lParam;            32-bit message parameter
  644. //    
  645. //DESCRIPTION:
  646. //
  647. //    'SaveAs' file name dialog box.
  648. //
  649. //RETURN:
  650. //
  651. //    TRUE if a message was processed.
  652. //    FALSE if not.
  653. //-------------------------------------------------------------------------
  654.  
  655. BOOL FAR PASCAL
  656. OpenDlgProc(HWND hDlg, WORD Msg, WORD wParam, LONG lParam)
  657. {
  658.     static char     EditText[128];
  659.     char    *p;
  660.  
  661.     switch (Msg)
  662.     {
  663.         case WM_INITDIALOG:
  664.             // Set the text entry control's limit to
  665.             // 127 characters.
  666.  
  667.             SendDlgItemMessage(hDlg, IDD_FNAME, EM_LIMITTEXT, 127, 0L);
  668.  
  669.             // Initialize it with the current file name.
  670.  
  671.             lstrcpy((LPSTR)EditText, (LPSTR)AvssFileName);
  672.             SetDlgItemText(hDlg, IDD_FNAME, EditText);
  673.             return TRUE;
  674.  
  675.         case WM_COMMAND:
  676.             switch (wParam)
  677.             {
  678.                 case IDOK:
  679.                     // Retrieve the entered file name. 
  680.                     GetDlgItemText(hDlg, IDD_FNAME, (LPSTR)EditText, 127);
  681.  
  682.                     if (*EditText)
  683.                     {
  684.                         // Chop off the extension,
  685.                         // if present.
  686.  
  687.                         if ((p = strchr(EditText, '.')) != NULL)
  688.                             *p = '\0';
  689.  
  690.                         // Build filespec with .avs
  691.                         // extension.
  692.  
  693.                         strcpy(AvssFileName, EditText);
  694.                         strcat(AvssFileName, ".avs");
  695.  
  696.                         EndDialog(hDlg, TRUE);
  697.                         return TRUE;
  698.                     }
  699.  
  700.                     // FALL THROUGH !!!  If no
  701.                     // filespec, we consider that
  702.                     // the same as cancelling.
  703.  
  704.                 case IDCANCEL:
  705.                     EndDialog(hDlg, FALSE);
  706.                     return TRUE;
  707.             }
  708.             break;
  709.     }
  710.     return FALSE;
  711. }
  712.  
  713. //-------------------------------------------------------------------------
  714. //FUNCTION:                                 
  715. //    
  716. //    VOID UpdateMenus(State)
  717. //
  718. //PARMS IN:
  719. //
  720. //    WORD     State;        state value from the capture engine.
  721. //    
  722. //DESCRIPTION:
  723. //
  724. //    This function enables/disables the appropriate menu items based
  725. //    on the state of the capture engine.  It displays the current 
  726. //    state in the caption on the main window's title bar.
  727. //    
  728. //-------------------------------------------------------------------------
  729.  
  730. VOID
  731. UpdateMenus(WORD State)
  732. {
  733.     BOOL    bMonitor;
  734.     BOOL    bCapture;
  735.     BOOL    bExit;
  736.     HMENU    hMenu;
  737.     char    WindowCaption[48];
  738.  
  739.     switch (State)
  740.     {
  741.         case ST_UNINITIALIZED:
  742.             bMonitor = MENUITEM_OFF;
  743.             bCapture = MENUITEM_OFF;
  744.             bExit    = MENUITEM_ON;
  745.             break;
  746.  
  747.         case ST_INITIALIZED:
  748.             bMonitor = MENUITEM_ON;
  749.             bCapture = MENUITEM_OFF;
  750.             bExit    = MENUITEM_ON;
  751.             break;
  752.  
  753.         case ST_MONITORING:
  754.             bMonitor = MENUITEM_ON;
  755.             bCapture = MENUITEM_ON;
  756.             bExit    = MENUITEM_OFF;
  757.             break;
  758.  
  759.         case ST_CAPTURING:
  760.             bMonitor = MENUITEM_OFF;
  761.             bCapture = MENUITEM_ON;
  762.             bExit    = MENUITEM_OFF;
  763.             break;
  764.             
  765.         default:
  766.             return;
  767.     }
  768.  
  769.     // Get a handle to the main window's menu.
  770.  
  771.     hMenu = GetMenu(hwndMain);
  772.  
  773.     // Enable/disable menu options.
  774.  
  775.     EnableMenuItem(hMenu, IDM_MONITOR, bMonitor);
  776.     EnableMenuItem(hMenu, IDM_CAPTURE, bCapture);
  777.     EnableMenuItem(hMenu, IDM_EXIT,    bExit);
  778.  
  779.     // Redraw the updated menu bar.
  780.  
  781.     DrawMenuBar(hwndMain);
  782.  
  783.     // Display the current state on the title bar.
  784.  
  785.     wsprintf((LPSTR)WindowCaption, (LPSTR)"AvkCapt - %s", 
  786.       (LPSTR)pStateName[State]);
  787.  
  788.     SetWindowText(hwndMain, WindowCaption);
  789. }
  790.